package org.mall.modules.order.controller.users;
import lombok.extern.slf4j.Slf4j;
import org.mall.common.api.vo.CommonResult;
import org.mall.common.exception.ServiceException;
import org.mall.common.system.util.JwtUtil;
import org.mall.common.util.ObjectUtils;
import org.mall.common.util.json.JacksonUtils;
import org.mall.convert.order.application.CartConvert;
import org.mall.modules.order.service.CartService;
import org.mall.modules.order.service.OrderService;
import org.mall.modules.pojo.order.bo.CalcOrderPriceBO;
import org.mall.modules.pojo.order.bo.CalcSkuPriceBO;
import org.mall.modules.pojo.order.bo.CartItemBO;
import org.mall.modules.pojo.order.dto.CalcOrderPriceDTO;
import org.mall.modules.pojo.order.vo.UserCartReqBodyParams;
import org.mall.modules.pojo.order.vo.UsersCalcSkuPriceVO;
import org.mall.modules.pojo.order.vo.UsersCartDetailVO;
import org.mall.modules.pojo.order.vo.UsersOrderConfirmCreateVO;
import org.mall.modules.pojo.product.bo.ProductSkuDetailBO;
import org.mall.modules.pojo.promotion.bo.CouponCardAvailableBO;
import org.mall.modules.pojo.shop.ShopDTO;
import org.mall.modules.product.service.ProductSpuService;
import org.mall.modules.promotion.service.CouponService;
import org.mall.modules.shop.service.ShopService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

import static org.mall.common.api.vo.CommonResult.error;
import static org.mall.common.api.vo.CommonResult.success;


@RestController
@RequestMapping("/user/cart")
@Slf4j
public class UsersCartController {

    @Autowired
    private CartService cartService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private CouponService couponService;

    @Autowired
    private ShopService shopService;

    @Autowired
    private ProductSpuService productSpuService;

    @PostMapping("/add")
    public CommonResult<Integer> add(@RequestBody UserCartReqBodyParams params) {
        if (ObjectUtils.isNull(params.getQuantity(),params.getSkuId())){
            return error("参数错误");
        }
        // 添加到购物车
        cartService.add(JwtUtil.getUserIdByToken(), params.getSkuId(), params.getQuantity());

        // 获得目前购物车商品总数量
        return success(cartService.count(JwtUtil.getUserIdByToken()));
    }

    @PostMapping("/updateQuantity")
    public CommonResult<List<UsersCartDetailVO>>  updateQuantity(@RequestBody UserCartReqBodyParams params) {
        // 添加到购物车
        if (ObjectUtils.isNull(params.getQuantity(),params.getSkuId())){
            return error("参数错误");
        }
        cartService.updateQuantity(JwtUtil.getUserIdByToken(),
                params.getSkuId(), params.getQuantity());
        // 获得目前购物车明细
        return getCartDetail();
    }

    @PostMapping("/updateSelected")
    public CommonResult<List<UsersCartDetailVO>>  updateSelected(@RequestBody UserCartReqBodyParams params) {
        // 更新選擇狀態
        cartService.updateSelected(JwtUtil.getUserIdByToken(),params.getSkuIds().stream().map(Long::parseLong).collect(Collectors.toList()), params.getSelected());
        // 获得目前购物车明细
        return getCartDetail();
    }

    @GetMapping("/count")
    public CommonResult<Integer> count() {
        return success(cartService.count(JwtUtil.getUserIdByToken()));
    }

    @GetMapping("/list")
    public CommonResult<List<UsersCartDetailVO>>  list() { // TODO 芋艿，先暂用这个 VO 。等促销活动出来后，做调整
        return getCartDetail();
    }

    private CommonResult<List<UsersCartDetailVO>> getCartDetail() {
        List<UsersCartDetailVO> cartDetailVOS=new ArrayList<>();

        List<CartItemBO> cartItems = cartService.list(JwtUtil.getUserIdByToken(), null);
        List<Long> skuIds=cartItems.stream().map(CartItemBO::getSkuId).collect(Collectors.toList());
        List<ProductSkuDetailBO> skuDetailBOS= productSpuService.getProductSkuDetailList(skuIds);
        // 购物车为空时，构造空的 UsersOrderConfirmCreateVO 返回
        if (cartItems.isEmpty()) {

            cartDetailVOS=Collections.emptyList();
            return success(cartDetailVOS);
        }
        if (cartItems.size()>skuDetailBOS.size()){
            List<Long> deleteList=new ArrayList<>();

            int i =cartItems.size()-skuDetailBOS.size();

            for (CartItemBO cartItem : cartItems) {
                if (i==0){
                    break;
                }
               if (!skuDetailBOS.stream().anyMatch(o->{return cartItem.getSkuId().equals(o.getId());})){
                   deleteList.add(cartItem.getSpuId());
               }
                    i--;
            }
            cartService.deleteList(JwtUtil.getUserIdByToken(),deleteList);
            cartItems = cartService.list(JwtUtil.getUserIdByToken(), null);
        }
        Map<String,List<CartItemBO>> result=cartItems.stream().collect(Collectors.groupingBy(CartItemBO::getShopId));
        Iterator<String> iterator=result.keySet().iterator();
        CommonResult<List<ShopDTO>> commonResult=shopService.getShopInfoById(result.keySet().parallelStream().collect(Collectors.toList()));
        List<ShopDTO> shopDTOS;
        if (commonResult.getSuccess()){
            shopDTOS=commonResult.getData();
        }else {
            shopDTOS=new ArrayList<>();
        }
        UsersCartDetailVO detailVOTemp;
        while (iterator.hasNext()){
            String shopId=iterator.next();
            List<CartItemBO> temp=result.get(shopId);
            CalcOrderPriceBO calcOrder = list0(temp, null);
            detailVOTemp= CartConvert.INSTANCE.convert2(calcOrder).setShopId(shopId).setShopName(shopDTOS.stream().
                    filter(shopDTO ->shopId.equals( shopDTO.getId())).findFirst().orElse(new ShopDTO()).getShopName());
            detailVOTemp.getItemGroups().stream().forEach(itemGroup -> {itemGroup.getItems().forEach(sku ->
                    {
                        ProductSkuDetailBO s=skuDetailBOS.stream().filter(skuDetailBO->(skuDetailBO.getId().equals(sku.getId()))).
                                findFirst().orElse(new ProductSkuDetailBO());
                        sku.setName(s.getTitle());sku.setPicURL(s.getPicURL());
                        log.info("stream"+ JacksonUtils.toJSONString(s));
                    })
                    ;}
            );
            cartDetailVOS.add(detailVOTemp);
        }
        // 计算商品价格

        // 执行数据拼装
        return success(cartDetailVOS);
    }

    @GetMapping("/confirmCreateOrder")
    public CommonResult<UsersOrderConfirmCreateVO> getConfirmCreateOrder(@RequestParam(value = "couponCardId", required = false) Integer couponCardId) {
        String userId = JwtUtil.getUserIdByToken();
        // 获得购物车中选中的
        List<CartItemBO> cartItems = cartService.list(userId, true);
        // 购物车为空时，构造空的 UsersOrderConfirmCreateVO 返回
        if (cartItems.isEmpty()) {
            UsersOrderConfirmCreateVO result = new UsersOrderConfirmCreateVO();
            result.setItemGroups(Collections.emptyList());
            result.setFee(new UsersOrderConfirmCreateVO.Fee(0, 0, 0, 0));
            return success(result);
        }
        Set<String> keySet=cartItems.stream().collect(Collectors.groupingBy(CartItemBO::getShopId)).keySet();
        if (keySet.size()>1){
            throw new ServiceException(1,"选中的商品不是同一家商店");
        }

        // 计算商品价格
        CalcOrderPriceBO calcOrderPrice = list0(cartItems, couponCardId);
        // 获得优惠劵
        List<CouponCardAvailableBO> couponCards = couponService.getCouponCardList(userId,
                CartConvert.INSTANCE.convertList(calcOrderPrice.getItemGroups()));
        // 执行数据拼装
        CommonResult<ShopDTO> result= shopService.getOneShopInfoByShopId(keySet.iterator().hasNext()?keySet.iterator().next():"");
        UsersOrderConfirmCreateVO vo=CartConvert.INSTANCE.convert(calcOrderPrice).setCouponCards(couponCards);
        if (result.isSuccess()&&result.getData()!=null){
            vo.setShopId(result.getData().getId());
            vo.setShopName(result.getData().getShopName());
        }
        return success(vo);
    }

    private CalcOrderPriceBO list0(List<CartItemBO> cartItems, Integer couponCardId) {
        // 创建计算的 DTO
        CalcOrderPriceDTO calcOrderPriceDTO = new CalcOrderPriceDTO()
                .setUserId(JwtUtil.getUserIdByToken())
                .setItems(new ArrayList<>(cartItems.size()))
                .setCouponCardId(couponCardId);
        for (CartItemBO item : cartItems) {
            calcOrderPriceDTO.getItems().add(new CalcOrderPriceDTO.Item(item.getSkuId(), item.getQuantity(), item.getSelected()));
        }
        // 执行计算
        return cartService.calcOrderPrice(calcOrderPriceDTO);
    }

    @GetMapping("/calcSkuPrice")
    public CommonResult<UsersCalcSkuPriceVO> calcSkuPrice(@RequestParam("skuId") Long skuId) {
        // 计算 sku 的价格
        CalcSkuPriceBO calcSkuPrice = cartService.calcSkuPrice(skuId);
        return success(CartConvert.INSTANCE.convert2(calcSkuPrice));
    }
    @PostMapping("/delete")
    public CommonResult delete(@RequestBody UserCartReqBodyParams params) {
        if (ObjectUtils.isNull(params.getSkuIds())){
            return error("参数错误");
        }

        cartService.deleteList(JwtUtil.getUserIdByToken(), params.getSkuIds().stream().map(Long::parseLong).collect(Collectors.toList()));
        // 获得目前购物车商品总数量
        return success("删除成功");
    }
    public CommonResult<Object> confirmOrder() {
        // 查询购物车列表（选中的）
//        cartService.list(userId, true);
        // 查询确认订单信息的明细

        return null;
    }

    @PostMapping("/deleteByShopId")
    public CommonResult deleteByShopId(@RequestBody UserCartReqBodyParams params) {
        if (ObjectUtils.isNull(params.getShopId())){
            return error("参数错误");
        }
        // 物理删除商品
        cartService.deleteByShopId(JwtUtil.getUserIdByToken(), params.getShopId());
        return success("删除成功");
    }

}
